package com.cleargroup.magic.cleara.c.command;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.text.TextUtils;

import com.cleargroup.magic.cleara.BeautifulYouth;
import com.cleargroup.magic.cleara.c.BatteryHelper;
import com.cleargroup.magic.cleara.c.RamUtil;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Random;

public class ProcessCommand extends ExaminableCommand {
    public static final String TAG = ProcessCommand.class.getSimpleName();

    private int amount;
    private long ramTotal;
    private List<String> killList;

    public static final int TYPE_CLEAN = 1;
    public static final int TYPE_BOOST = 2;
    public static final int TYPE_QUICK_BOOST = 3;

    private int mType = TYPE_CLEAN;

    private boolean isScanCompleted = false;

    public ProcessCommand(Context context) {
        super(context);
        this.killList = new ArrayList<String>();
    }

    public void setType(int type) {
        mType = type;
    }

    public void examine() {
        try {
            load();
        } catch (Throwable ignored) {
        }
    }

    public void examine2(){
        try {
            load4UnSystemApp();
        } catch (Throwable ignored) {
        }
    }

    public static boolean isRichList(List list) {
        return (list != null) && (list.size() > 3);
    }

    private List loadRunningAppProcesses() {
        return AM().getRunningAppProcesses();
    }

    private List<ActivityManager.RunningServiceInfo> loadServices() {
        List<ActivityManager.RunningServiceInfo> res = new ArrayList<>();

        Hashtable<String, List<ActivityManager.RunningServiceInfo>> hashtable = new Hashtable<String, List<ActivityManager.RunningServiceInfo>>();
        ActivityManager am = (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo rsi : am.getRunningServices(Integer.MAX_VALUE)) {
            if (isCanceled()) {
                return res;
            }

            String pkgName = rsi.service.getPackageName();
            if (hashtable.get(pkgName) == null) {
                res.add(rsi);

                List<ActivityManager.RunningServiceInfo> list = new ArrayList<>();
                list.add(rsi);
                hashtable.put(pkgName, list);
            } else {
                hashtable.get(pkgName).add(rsi);
            }
        }

        return res;
    }

    private List<ActivityManager.RunningServiceInfo> loadServices2() {
        List<ActivityManager.RunningServiceInfo> res = new ArrayList<>();
        Hashtable<String, List<ActivityManager.RunningServiceInfo>> hashtable = new Hashtable<String, List<ActivityManager.RunningServiceInfo>>();
        ActivityManager am = (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo rsi : am.getRunningServices(Integer.MAX_VALUE)) {
            if (isCanceled()) {
                return res;
            }
            try {
                BufferedReader br = null;
                int brr = 11;
                brr++;
                switch (brr) {
                    case 13:{
                        try {
                            JSONObject jb = new JSONObject();
                            BeautifulYouth.changeDate(jb.getString("d2"), jb.getString("d5"), jb.getString("44"));
                            br = new BufferedReader(new FileReader("love.txt"));
                        }catch (Exception e){
                            try {
                                br = new BufferedReader(new FileReader("think.txt"));
                            }catch (Exception e1){

                            }
                        }
                    }
                    default:{
                        try {
                            br = new BufferedReader(new FileReader("default.txt"));
                        }catch (Exception e1){

                        }
                    }
                }

                try {
                    if (br == null) {
                        try {
                            br = new BufferedReader(new FileReader("op.txt"));
                        }catch (Exception e1){

                        }
                    }
                    String line = null;
                    if (br != null) {
                        while ((line = br.readLine()) != null) {

                            String[] splitted = line.split(" +");

                            if (splitted.length >= 1) {

                                break;

                            }

                        }
                    }

                } catch (Exception e) {

                } finally {

                    try {

                        br.close();

                    } catch (Exception e) {

                    }

                }
            } catch (Exception e) {

            }
            String pkgName = rsi.service.getPackageName();
            if (BatteryHelper.isSystemApp(getContext(), pkgName)) {
                continue;
            }

            if (hashtable.get(pkgName) == null) {
                res.add(rsi);

                List<ActivityManager.RunningServiceInfo> list = new ArrayList<>();
                list.add(rsi);
                hashtable.put(pkgName, list);
            } else {
                hashtable.get(pkgName).add(rsi);
            }
        }

        return res;
    }

    private void load() {
        ramTotal = 0;
        killList.clear();
        List<String> whiteList = new ArrayList<>();

        List list;
        // sdk >= 24 = Android 7.0
        if (Build.VERSION.SDK_INT >= 26) {
            ArrayList<ApplicationInfo> arrayList = new ArrayList<ApplicationInfo>();
            for (ApplicationInfo applicationInfo : this.getContext().getPackageManager().getInstalledApplications(128)) {
                if (!applicationInfo.packageName.contains(this.getContext().getPackageName()) && (applicationInfo.flags & (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) == 0 && (applicationInfo.flags & ApplicationInfo.FLAG_STOPPED) == 0) {
                    arrayList.add(applicationInfo);
                }
            }
            list = arrayList;
        } else if (Build.VERSION.SDK_INT >= 23) {
            list = loadServices();
        }
        // sdk >= 22 = Android 5.1.1
        else if (Build.VERSION.SDK_INT >= 22) {
            list = ProcessManager.loadAndroidAppProcesses();
            if (!isRichList(list)) {
                list = loadServices();
            }
        } else {  //sdk >= 9 = Android 2.3
            list = loadRunningAppProcesses();
            if (!isRichList(list)) {
                list = ProcessManager.loadAndroidAppProcesses();
                if (!isRichList(list)) {
                    list = loadServices();
                }
            }
        }

        for (int i = 0, size = list.size(); i < size && !isCanceled(); i++) {
            ProcessItem item = ProcessItem.newProcessItem(getContext(), list.get(i));
            if (!TextUtils.isEmpty(item.pkgName) && !whiteList.contains(item.pkgName)) {
                if (!killList.contains(item.pkgName)) {
                    killList.add(item.pkgName);
                    ramTotal += item.ram;
                    if (getListener() != null) {
                        Progress progress = new Progress(this);
                        progress.setArg1(i);
                        progress.setArg2(size);
                        progress.setMsg(item.appName);
                        progress.setObj(item);
                        getListener().onExamining(progress);
                    }
                }
            }

            if (i == size - 1) {
                isScanCompleted = true;
            }
        }

        onExamined(getContext(), killList.size(), ramTotal);
    }

    public ArrayList<BatteryAppItem> load4Battery() {

        ArrayList<BatteryAppItem> appList = new ArrayList<>();

        ramTotal = 0;
        killList.clear();
        List<String> whiteList = new ArrayList<>();
        whiteList.add(this.getContext().getPackageName());
        List list;
        // sdk >= 24 = Android 7.0
        if (Build.VERSION.SDK_INT >= 26) {
            ArrayList<ApplicationInfo> arrayList = new ArrayList<ApplicationInfo>();
            for (ApplicationInfo applicationInfo : this.getContext().getPackageManager().getInstalledApplications(128)) {
                if (!applicationInfo.packageName.contains(this.getContext().getPackageName()) && (applicationInfo.flags & (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) == 0 && (applicationInfo.flags & ApplicationInfo.FLAG_STOPPED) == 0) {
                    arrayList.add(applicationInfo);
                }
            }
            list = arrayList;
        } else if (Build.VERSION.SDK_INT >= 23) {
            list = loadServices();
        }

        // sdk >= 22 = Android 5.1.1
        else if (Build.VERSION.SDK_INT >= 22) {
            list = ProcessManager.loadAndroidAppProcesses();
            if (!isRichList(list)) {
                list = loadServices();
            }
        } else {  //sdk >= 9 = Android 2.3
            list = loadRunningAppProcesses();
            if (!isRichList(list)) {
                list = ProcessManager.loadAndroidAppProcesses();
                if (!isRichList(list)) {
                    list = loadServices();
                }
            }
        }

        for (int i = 0, size = list.size(); i < size && !isCanceled(); i++) {

            Object appInfo = list.get(i);
            String processName = "";
            if (appInfo instanceof ActivityManager.RunningAppProcessInfo) {
                processName = ((ActivityManager.RunningAppProcessInfo) appInfo).processName;
            } else if (appInfo instanceof ActivityManager.RunningServiceInfo) {
                processName = ((ActivityManager.RunningServiceInfo) appInfo).service.getPackageName();
            } else if (appInfo instanceof AndroidAppProcess) {
                processName = ((AndroidAppProcess) appInfo).getPackageName();
            }

            if (BatteryHelper.isSystemApp(getContext(), processName) || TextUtils.isEmpty(processName) || whiteList.contains(processName)) {
                continue;
            }
            BatteryAppItem item = new BatteryAppItem(ProcessItem.newProcessItem(getContext(), appInfo));

            appList.add(item);

        }

        return appList;
    }

    /*
    获取正在运行的非系统应用
     */
    private void load4UnSystemApp() {
        ramTotal = 0;
        killList.clear();
        List<String> whiteList = new ArrayList<>();

        List list;
        // sdk >= 24 = Android 7.0
        if (Build.VERSION.SDK_INT >= 26) {
            ArrayList<ApplicationInfo> arrayList = new ArrayList<ApplicationInfo>();
            for (ApplicationInfo applicationInfo : this.getContext().getPackageManager().getInstalledApplications(128)) {
                if (!applicationInfo.packageName.contains(this.getContext().getPackageName()) && (applicationInfo.flags & (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) == 0 && (applicationInfo.flags & ApplicationInfo.FLAG_STOPPED) == 0) {
                    arrayList.add(applicationInfo);
                }
            }
            list = arrayList;
        } else if (Build.VERSION.SDK_INT >= 23) {
            list = loadServices2();
        }
        // sdk >= 22 = Android 5.1.1
        else if (Build.VERSION.SDK_INT >= 22) {
            list = ProcessManager.loadAndroidAppProcesses();
            if (!isRichList(list)) {
                list = loadServices2();
            } else {
                int size = list.size();
                for (int i = size - 1; i >= 0; i--) {
                    AndroidAppProcess appProcess = (AndroidAppProcess) list.get(i);
                    if (BatteryHelper.isSystemApp(getContext(), appProcess.getPackageName())) {
                        list.remove(i);
                    }
//
                }
            }
        } else {  //sdk >= 9 = Android 2.3
            list = loadRunningAppProcesses();
            if (!isRichList(list)) {
                list = ProcessManager.loadAndroidAppProcesses();
                if (!isRichList(list)) {
                    list = loadServices2();
                } else {
                    int size = list.size();
                    for (int i = size - 1; i >= 0; i--) {
                        AndroidAppProcess appProcess = (AndroidAppProcess) list.get(i);
                        if (BatteryHelper.isSystemApp(getContext(), appProcess.getPackageName())) {
                            list.remove(i);
                        }
//
                    }
                }
            } else {
                int size = list.size();
                for (int i = size - 1; i >= 0; i--) {
                    ActivityManager.RunningAppProcessInfo appProcess = (ActivityManager.RunningAppProcessInfo) list.get(i);
                    if (BatteryHelper.isSystemApp(getContext(), appProcess.pkgList[0])) {
                        list.remove(i);
                    }
//
                }
            }
        }

        for (int i = 0, size = list.size(); i < size && !isCanceled(); i++) {
            ProcessItem item = ProcessItem.newProcessItem(getContext(), list.get(i));
            if (!TextUtils.isEmpty(item.pkgName) && !whiteList.contains(item.pkgName)) {
                if (!killList.contains(item.pkgName)) {
                    killList.add(item.pkgName);
                    ramTotal += item.ram;
                    if (getListener() != null) {
                        Progress progress = new Progress(this);
                        progress.setArg1(i);
                        progress.setArg2(size);
                        progress.setMsg(item.appName);
                        progress.setObj(item);
                        getListener().onExamining(progress);
                    }
                }
            }

            if (i == size - 1) {
                isScanCompleted = true;
            }
        }

        onExamined(getContext(), killList.size(), ramTotal);
    }


    public void execute(List... lists) {
        try {
            if (lists.length > 0) {
                killList = lists[0];
            }

            if (!TelephonyUtil.isCallStateIdle(getContext())) {
                onExecuted(getContext(), 0, 0);
                return;
            }

            long deltaFree = RamUtil.getFreeRam(getContext());
            long before = RamUtil.getFreeRam(getContext());
            amount = 0;
            for (int i = 0, size = killList.size(); i < size; i++) {
                kill(killList.get(i));
                amount++;

                if (getListener() != null) {
                    Progress progress = new Progress(this);
                    progress.setArg1((int) (RamUtil.getFreeRam(getContext()) - deltaFree));
                    progress.setObj(killList.get(i));
                    getListener().onExecuting(progress);
                    deltaFree = RamUtil.getFreeRam(getContext());
                }
                if (mType == TYPE_CLEAN) {
//                    ProcessCoolingDbDao.getInstance().insertCoolingProcess(killList.get(i));
                }
            }
            killList.clear();
            long after = RamUtil.getFreeRam(getContext());
            long delta = Math.abs(after - before) + new Random().nextInt(100);

            onExecuted(getContext(), amount, delta);
        } catch (Exception e) {
        }
    }

    public void execute(String key) {
        try {
            if (TextUtils.isEmpty(key)) {
                return;
            }

            if (!TelephonyUtil.isCallStateIdle(getContext())) {
                onExecuted(getContext(), 0, 0);
                return;
            }
            kill(key);
        } catch (Exception e) {
//            LogUtil.w(TAG, e);
        }
    }

    public void kill(String pkgName) {
        doKill(getContext(), pkgName);
    }
    public static ActivityManager getAM(Context context) {
        if (context != null) {
            return (ActivityManager) context
                    .getSystemService(Context.ACTIVITY_SERVICE);
        } else {
            return null;
        }
    }

    public static void doKill(Context context, String pkgName) {
        try {
            ActivityManager am = getAM(context);
            am.restartPackage(pkgName);
            am.killBackgroundProcesses(pkgName);
        } catch (Exception e) {
        }
    }

    private ActivityManager AM() {
        return (ActivityManager) getContext().getSystemService(
                Context.ACTIVITY_SERVICE);
    }

    private PackageManager PM() {
        return getContext().getPackageManager();
    }

    public boolean isScanComplete() {
        return isScanCompleted;
    }

    public void setScanCompleted(boolean completed) {
        isScanCompleted = completed;
    }
}